package com.meta.platform.sms.service.invoke.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.github.pagehelper.util.StringUtil;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import com.meta.framework.common.exception.CustomException;
import com.meta.framework.util.BeanUtil;
import com.meta.platform.sms.config.AliSmsPushConfig;
import com.meta.platform.sms.constants.SmsChannel;
import com.meta.platform.sms.domain.SmsConfig;
import com.meta.platform.sms.request.InvokeThirdSmsParam;
import com.meta.platform.sms.request.SendSmsParam;
import com.meta.platform.sms.service.invoke.InvokeThirdSmsService;
import com.meta.platform.sms.utils.PhoneUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.*;

@Service("aliSms")
@Slf4j
public class AliSmsInvokeServiceImpl implements InvokeThirdSmsService {

	static IAcsClient acsClient = null;

	static IAcsClient getClient() {
		if (acsClient == null) {
			IClientProfile profile = DefaultProfile.getProfile(AliSmsPushConfig.endPoint, AliSmsPushConfig.accessKey,
					AliSmsPushConfig.secret);
			try {
				DefaultProfile.addEndpoint(AliSmsPushConfig.endPoint, AliSmsPushConfig.endPoint, AliSmsPushConfig.product, AliSmsPushConfig.domain);
			} catch (ClientException e) {
				log.error("Exception init client", e);
			}
			acsClient = new DefaultAcsClient(profile);
		}
		return acsClient;
	}

	@Override
	public String outerSmsChannelName() {
		return SmsChannel.ALI.channel;
	}

	@Override
	public InvokeThirdSmsParam generateInvokeParam(SmsConfig smsConfig, SendSmsParam originalParam) {
		InvokeThirdSmsParam result = new InvokeThirdSmsParam();
		BeanUtil.copyProperties(smsConfig, result);
		result.setMobiles(originalParam.getMobiles());
		result.setNativeCode(originalParam.getNativeCode());
		result.setBizId(UUID.randomUUID().toString());
		String smsParams = originalParam.getSmsParams();
		result.setOriginalSmsParam(smsParams);
		String outerSmsTemplate = smsConfig.getOuterSmsTemplate();
		if (Strings.isNullOrEmpty(smsParams)) {
			result.setFinalSmsContent(smsParams);
			return result;
		}
		JSONObject object = JSON.parseObject(smsParams);
		Set<String> jsonKeySets = object.keySet();
		Map<String, Object> params = new HashMap<>();
		for (String key : jsonKeySets) {
			params.put(key, object.get(key));
		}

		boolean flag = true;
		int count = 0;
		while (flag && count < 5) { //最多5个变量替换
			count++;
			int startIndex = outerSmsTemplate.indexOf("${");
			if (startIndex > -1) {
				int endIndex = outerSmsTemplate.indexOf("}");
				String currentParamName = outerSmsTemplate.substring(startIndex + 2, endIndex);
				String replaceContext = "${" + currentParamName + "}";
				outerSmsTemplate = outerSmsTemplate.replace(replaceContext, params.get(currentParamName).toString());

			} else {
				flag = false;
			}
		}
		result.setFinalSmsContent(outerSmsTemplate);
		return result;
	}

	private String getPhones(String nativeCode, Set<String> phones) {
		if (!Strings.isNullOrEmpty(nativeCode) && CollectionUtils.isNotEmpty(phones) && !PhoneUtils.getLocal().equals(nativeCode)) {
			log.info("阿里短信通道转换为国际号码格式 {} 区号 {}", Joiner.on(",").join(phones), nativeCode);
			Set<String> newPhones = Sets.newHashSet();
			phones.forEach(phone -> {
						newPhones.add("00" + nativeCode + phone);
					}
			);
			return Joiner.on(",").join(newPhones);
		}
		return Joiner.on(",").join(phones);
	}

	@Override
	public Boolean invokeThirdSmsService(InvokeThirdSmsParam invokeThirdSmsParam) {
		if (StringUtil.isEmpty(AliSmsPushConfig.endPoint)) {
			log.info("阿里云地址配置为空 ");
			return false;
		}

		SendSmsRequest request = new SendSmsRequest();
		//使用post提交
		request.setMethod(MethodType.POST);
		//必填:待发送手机号。支持以逗号分隔的形式进行批量调用，批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
		request.setPhoneNumbers(getPhones(invokeThirdSmsParam.getNativeCode(), new HashSet<>(invokeThirdSmsParam.getMobiles())));
		//必填:短信签名-可在短信控制台中找到
		request.setSignName(invokeThirdSmsParam.getSignName());
		//必填:短信模板-可在短信控制台中找到
		request.setTemplateCode(invokeThirdSmsParam.getOuterSmsTemplateCode());
		//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
		//友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
		request.setTemplateParam(invokeThirdSmsParam.getOriginalSmsParam());

		SendSmsResponse sendSmsResponse = new SendSmsResponse();
		try {
			sendSmsResponse = getClient().getAcsResponse(request);
		} catch (ClientException e) {
			e.printStackTrace();
		}
		if (sendSmsResponse.getCode() != null) {
			if (sendSmsResponse.getCode().equals("OK")) {
				log.info("send aliyun success send text is {} successfully", JSON.toJSONString(invokeThirdSmsParam));
				return true;
			}
			if (sendSmsResponse.getCode().equals("isv.BUSINESS_LIMIT_CONTROL")) {
				throw new CustomException("请耐心等待，1分钟内不要重复发送。");
			} else {
				log.info("send aliyun success send text is {} failed ,fail code is {}", JSON.toJSONString(invokeThirdSmsParam), sendSmsResponse.getCode());
				return false;
			}

		}
		return false;
	}
}
